#include "StdAfx.h"
#include "AddAgenda.h"
#include "UserDoesNotExist.h"
#include "InvalidPassword.h"
#include "InvalidInterval.h"
#include "MeetingAlreadyExist.h"
#include "TimeOverlap.h"
#include <algorithm>
#include "InviterCannotBeInvitee.h"

using namespace std;

AddAgenda::AddAgenda(string inviterName, string password, string inviteeName, string startTime, string endTime, string title)
{
	this->inviterName = inviterName;
	this->password = password;
	this->inviteeName = inviteeName;
	this->startTime = startTime;
	this->endTime = endTime;
	this->title = title;
}


AddAgenda::~AddAgenda(void)
{
}

bool AddAgenda::doAction(UserCollection& uc, MeetingCollection& mc)
{
	//many many guard to provide the wrong input

	if( !uc.hasUser(inviterName) )
		throw UserDoesNotExist();
	if( !uc.isValid( inviterName, password ) )
		throw InvalidPassword();
	if( !uc.hasUser(inviteeName) )
		throw UserDoesNotExist();
	
	if( inviterName == inviteeName )
		throw InviterCannotBeInvitee();

	Interval interval( startTime, endTime );

	if( ! interval.isValid() )
		throw InvalidInterval();

	if( mc.hasMeeting(title) )
		throw MeetingAlreadyExist();

	User &inviter = uc.getUserByName(inviterName);
	User &invitee = uc.getUserByName(inviteeName);
	
	set<int>::iterator it;

	set<int> inviterMeetingIds = inviter.getMeetingIds();
	
	/* travese each meeting to find weather there is a TimeOverlap */

	for( it = inviterMeetingIds.begin(); it != inviterMeetingIds.end(); it++ )
	{
		Meeting meeting = mc.getMeetingById( *it );
		if( meeting.getInterval().contains(interval) || interval.contains( meeting.getInterval() ) || meeting.getInterval().isOverlap(interval) )
			throw TimeOverlap();
	}

	set<int> inviteeMeetingIds = invitee.getMeetingIds();
	
	for( it = inviteeMeetingIds.begin(); it != inviteeMeetingIds.end(); it++ )
	{
		Meeting meeting = mc.getMeetingById( *it );
		if( meeting.getInterval().contains(interval) || interval.contains( meeting.getInterval() ) || meeting.getInterval().isOverlap(interval) )
			throw TimeOverlap();
	}
	
	//add the new meeting to the meetingCollection and the inviter's meeting list and invitee's meeting list
	int meetingId = mc.getMeetingIdSeq();
	inviter.addMeetingId(meetingId);
	invitee.addMeetingId(meetingId);
	mc.addMeeting( title, inviter, invitee, interval );

	return true;
}//modify